// server.ts
import { CompleteMultipartUploadCommand, CreateMultipartUploadCommand, S3Client, UploadPartCommand } from '@aws-sdk/client-s3';
import { NodeHttpHandler } from '@aws-sdk/node-http-handler';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import cors from 'cors';
import dotenv from 'dotenv';
import express from 'express';
import { Agent } from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
dotenv.config();

const proxyAgent = new HttpsProxyAgent('http://squid.caiwu.corp:3128');


const app = express();
// 创建不验证证书的 HTTP Agent
const agent = new Agent({
  rejectUnauthorized: false,          // 跳过证书验证
  keepAlive: true,                    // 保持长连接
  maxSockets: 100,                     // 提升并发连接数
  // maxVersion: 'TLSv1.2', // 强制使用 TLS 1.2
});

console.log(process.env.AWS_REGION)
const s3Client = new S3Client({
  logger: console, // 直接输出日志到控制台
  clientLogMode: 'debug', // 详细日志模式
  region: process.env.AWS_REGION,
  endpoint: process.env.AWS_S3_ENDPOINT,
  forcePathStyle: true,
  // s3ForcePathStyle: false,
  // retryer: {
  //   maxAttempts: 5,
  //   delay: 1000, // 基础重试间隔
  // },
  //maxAttempts: 3,           // 覆盖默认值（默认 3）
  //retryMode: 'standard',    // 或 'adaptive'
  //retryMode: 'adaptive',    // 或 'standard'
  // retryDelay: (attempt) => Math.min(2 ** attempt * 1000, 30000), // 指数退避上限 30 秒
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
  //tls: true,
  requestHandler: new NodeHttpHandler({
    //httpsAgent: agent,
    // socketTimeout: 120_000           // 底层套接字超时
    //httpAgent: proxyAgent,
    // requestTimeout: 120_000,     // 请求超时 120 秒
    // connectionTimeout: 30_000,        // 连接超时 30 秒
  }),
  signatureVersion: 'v2',

});

app.use(cors());
app.use(express.json());

// 初始化分块上传
app.post('/api/initiate-upload', async (req, res) => {
  try {
    const { fileName, fileType } = req.body;
    console.log(fileName, fileType)
    
    const command = new CreateMultipartUploadCommand({
      Bucket: process.env.S3_BUCKET_NAME,
      Key: fileName,
      ContentType: fileType,
    });
    // console.log('command', command)

    
    const response = await s3Client.send(command);
    res.json({ uploadId: response.UploadId });
  } catch (error) {
    // console.error('Initiate upload error:', error);
    res.status(500).json({ error: error });
  }
});


// 生成预签名URL
app.post('/api/generate-presigned-url', async (req, res) => {
  try {
    const { fileName, uploadId, partNumber } = req.body;
    
    const command = new UploadPartCommand({
      Bucket: process.env.S3_BUCKET_NAME,
      Key: fileName,
      UploadId: uploadId,
      PartNumber: partNumber,
    });
    
    const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 });
    res.json({ presignedUrl });
  } catch (error) {
    // console.error('Generate presigned URL error:', error);
    res.status(500).json({ error: error });
  }
});

// 完成分块上传
app.post('/api/complete-upload', async (req, res) => {
  try {
    const { fileName, uploadId, parts } = req.body;
    
    const command = new CompleteMultipartUploadCommand({
      Bucket: process.env.S3_BUCKET_NAME,
      Key: fileName,
      UploadId: uploadId,
      MultipartUpload: {
        Parts: parts.map((part) => ({
          PartNumber: part.PartNumber,
          ETag: part.ETag,
        })),
      },
    });
    
    const response = await s3Client.send(command);
    res.json({ location: response.Location });
  } catch (error) {
    // console.error('Complete upload error:', error);
    res.status(500).json({ error: error });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});